home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / pdf_draw.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  52.6 KB  |  1,771 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_draw.ps 9300 2008-12-21 07:46:52Z alexcher $
  14. % pdf_draw.ps
  15. % PDF drawing operations (graphics, text, and images).
  16.  
  17. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  18. .currentglobal true .setglobal
  19. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  20. GS_PDF_ProcSet begin
  21. pdfdict begin
  22.  
  23. % For simplicity, we use a single interpretation dictionary for all
  24. % PDF graphics operations, even though this is too liberal.
  25. /drawopdict 100 dict def
  26.  
  27. % ================================ Graphics ================================ %
  28.  
  29. % ---------------- Functions ---------------- %
  30.  
  31. % Note that resolvefunction converts a PDF Function to a PostScript Function;
  32. % resolve*fnproc converts a PDF function to a PostScript procedure.
  33. % We need to process all required and optional parameters to resolve any
  34. % use of indirect references.
  35.  
  36. /fnrdict mark
  37.   0 { .resolvefn0 }
  38.   2 { .resolvefn2 }
  39.   3 { .resolvefn3 }
  40.   4 { .resolvefn4 }
  41. .dicttomark readonly def
  42.  
  43. /.resolvefn0 {
  44.   dup length 1 add dict .copydict    % make room for DataSource
  45.   % now resolve any indirect references
  46.   dup /Size 2 copy knownoget { put } { pop pop } ifelse
  47.   dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse
  48.   dup /Order 2 copy knownoget { put } { pop pop } ifelse
  49.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  50.   dup /Decode 2 copy knownoget { put } { pop pop } ifelse
  51.   
  52.         % Don't lose our place in PDFfile.
  53.   PDFfile fileposition exch
  54.   dup //true resolvestream
  55.         % The stream isn't positionable, so read all the data now.
  56.         % Stack: filepos fndict stream
  57.   1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  58.   2 index /Size get { mul } forall
  59.   7 add 8 idiv
  60.   dup 65535 le {
  61.     string 1 index exch readstring pop
  62.   } {
  63.     1 index exch () /SubFileDecode filter /ReusableStreamDecode filter
  64.   } ifelse
  65.   exch closefile
  66.         % Stack: filepos fndict data
  67.   exch dup /DataSource 4 -1 roll put
  68.   exch PDFfile exch setfileposition
  69. } bdef
  70.  
  71. /.resolvefn2 {
  72.   dup length dict .copydict
  73.   dup /C0 2 copy knownoget { put } { pop pop } ifelse
  74.   dup /C1 2 copy knownoget { put } { pop pop } ifelse
  75.   dup /N 2 copy knownoget { put } { pop pop } ifelse
  76. } bdef
  77.  
  78. /.resolvefn3 {
  79.   dup length dict .copydict
  80.   dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  81.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  82.   dup /Functions 2 copy oget mark exch dup {
  83.     oforce .resolvefn
  84.   } forall
  85.   counttomark -1 roll astore exch pop put
  86. } bdef
  87.  
  88. /.resolvefn4 {
  89.   PDFfile fileposition exch             % filepos fndict
  90.   dup true resolvestream                % filepos fndict stream
  91.   exch dup length dict copy             % filepos stream fndict2
  92.   dup /Function undef                   % filepos stream fndict2
  93.   exch dup token not {
  94.     () /rangecheck cvx signalerror
  95.   } if
  96.   exch token {
  97.     /rangecheck cvx signalerror
  98.   } if
  99.         % Use .bind to avoid idiom recognition.
  100.   .bind
  101.   1 index /Function 3 -1 roll put
  102.   exch PDFfile exch setfileposition
  103. } bdef
  104.  
  105. /.resolvefn {        % <fndict> .resolvefn <fndict'>
  106.   dup length dict .copydict
  107.   dup /Domain 2 copy knownoget { put } { pop pop } ifelse
  108.   dup /Range 2 copy knownoget { put } { pop pop } ifelse
  109.   dup /FunctionType oget //fnrdict exch get exec
  110. } bdef
  111.  
  112. /resolvefunction {    % <fndict> resolvefunction <function>
  113.   .resolvefn
  114.   PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Function: ) print dup === flush } if } if
  115. } bdef
  116.  
  117. /resolvefnproc {    % <fndict> resolvefnproc <proc>
  118.   resolvefunction .buildfunction
  119. } bdef
  120.  
  121. /resolveidfnproc {    % <fndict> resolveidfnproc <proc>
  122.   dup /Identity eq { pop { } } { resolvefnproc } ifelse
  123. } bdef
  124.  
  125. /resolvedefaultfnproc {    % <fndict> <default> resolved'fnproc <proc>
  126.   1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  127. } bdef
  128.  
  129. % ---------------- Shadings ---------------- %
  130.  
  131. /shrdict mark
  132.   /BBox {
  133.     dup dup dup aload pop normrect_elems
  134.     5 -1 roll astore
  135.   } bind
  136.   /ColorSpace {
  137.     resolvecolorspace
  138.   } bind
  139.   /Function {
  140.     dup type /dicttype eq {
  141.       resolvefunction
  142.     } {
  143.       [ exch { oforce resolvefunction } forall ]
  144.     } ifelse
  145.   } bind
  146. .dicttomark readonly def
  147.  
  148. /resolveshading {    % <shadingstream> resolveshading <shading>
  149.   dup /.shading_dict .knownget {
  150.     exch pop 
  151.     dup /ShadingType get 4 ge {
  152.       dup /DataSource get 0 setfileposition
  153.     } if
  154.   } {
  155.     dup
  156.     PDFfile fileposition exch
  157.     mark exch {
  158.       oforce //shrdict 2 index .knownget { exec } if
  159.     } forall .dicttomark
  160.     dup /ShadingType get 4 ge {
  161.       dup dup true resolvestream
  162.         % Make a reusable stream so that the shading doesn't
  163.         % reposition PDFfile at unexpected times.
  164.       /ReusableStreamDecode filter /DataSource exch put
  165.     } if 
  166.     exch PDFfile exch setfileposition
  167.     dup 3 1 roll /.shading_dict exch put
  168.   } ifelse
  169. } bdef
  170. /resolvesh {        % <shname> resolvesh <shading>
  171.             % <shname> resolvesh <null>
  172.   Page /Shading rget {
  173.     resolveshading
  174.   } {
  175.     null
  176.   }ifelse
  177. } bdef
  178.  
  179. % ---------------- Halftones ---------------- %
  180.  
  181. /spotfunctions mark
  182.   /Round {
  183.     abs exch abs 2 copy add 1 le {
  184.       dup mul exch dup mul add 1 exch sub 
  185.     } {
  186.       1 sub dup mul exch 1 sub dup mul add 1 sub
  187.     } ifelse
  188.   }
  189.   /Diamond {
  190.     abs exch abs 2 copy add .75 le {
  191.       dup mul exch dup mul add 1 exch sub
  192.     } {
  193.       2 copy add 1.23 le {
  194.     .85 mul add 1 exch sub
  195.       } {
  196.     1 sub dup mul exch 1 sub dup mul add 1 sub
  197.       } ifelse
  198.     } ifelse
  199.   }
  200.   /Ellipse {
  201.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  202.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  203.     } {
  204.       dup 1 gt {
  205.     pop 1 exch sub dup mul exch 1 exch sub
  206.     .75 div dup mul add 4 div 1 sub
  207.       } {
  208.     .5 exch sub exch pop exch pop
  209.       } ifelse
  210.     } ifelse
  211.   }
  212.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  213.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  214.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  215.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  216.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  217.   /Line { exch pop abs neg }
  218.   /LineX { pop }
  219.   /LineY { exch pop }
  220.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  221.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  222.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  223.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  224.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  225.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  226.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  227.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  228.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  229.   /InvertedDouble {
  230.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  231.   }
  232. .dicttomark readonly def
  233.  
  234. /htrdict mark
  235.   1 { .resolveht1 }
  236.   5 { .resolveht5 }
  237.     % We don't support types 6, 10, or 16 yet.
  238. .dicttomark readonly def
  239.  
  240. /.resolveht1 {
  241.   mark exch {
  242.     oforce
  243.     1 index /SpotFunction eq {
  244.       dup type /nametype eq
  245.     { //spotfunctions exch get } { resolvefnproc }
  246.       ifelse
  247.     } {
  248.       1 index /TransferFunction eq {
  249.     resolveidfnproc
  250.       } if
  251.     } ifelse
  252.   } forall .dicttomark
  253. } bdef
  254.  
  255. /.resolveht5 {
  256.   mark exch {
  257.     oforce dup type /dicttype eq { resolvehalftone } if
  258.   } forall .dicttomark
  259. } bdef
  260.  
  261. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  262.   dup /HalftoneType get
  263.   dup //htrdict exch .knownget {
  264.     exch pop exec
  265.   } {
  266.     (\n\n   **** Unsupported HalftoneType ) pdfformaterror
  267.     =string cvs pdfformaterror (. ***\n\n) pdfformaterror
  268.     /resolvehalftone cvx /unregistered signalerror
  269.   } ifelse
  270. } bdef
  271.  
  272. % ---------------- Graphics state management ---------------- %
  273.  
  274. /cmmatrix matrix def
  275. drawopdict begin
  276.             % Graphics state stack
  277.   /q { q } def
  278.   /Q { Q } def
  279.             % Graphics state setting
  280.   /cm { //cmmatrix astore
  281.         .getpath      
  282.         exch concat
  283.         newpath { exec } forall
  284.     % If inside a BT/ET block, we need to update the TextSaveMatrix
  285.     currentdict /TextSaveMatrix .knownget {
  286.       //cmmatrix exch dup concatmatrix pop
  287.     } if
  288.       } bdef
  289.  
  290.   /i { 1 .min setflat } bdef
  291.   /J /setlinecap load def
  292.   /d /setdash load def
  293.   /j /setlinejoin load def
  294.   /w /setlinewidth load def
  295.   /M { 1 .max setmiterlimit } bdef
  296.   /gs { gs } def
  297. end
  298.  
  299. % Each entry in this dictionary is
  300. %    <gsres> <value> -proc- <gsres>
  301. /gsbg {
  302.   /BGDefault load resolvedefaultfnproc setblackgeneration
  303. } bdef
  304. /gsucr {
  305.   /UCRDefault load resolvedefaultfnproc setundercolorremoval
  306. } bdef
  307. /gstr {
  308.   dup type /arraytype eq {
  309.     { oforce /TRDefault load resolvedefaultfnproc } forall
  310.     setcolortransfer
  311.   } {
  312.     /TRDefault load resolvedefaultfnproc settransfer
  313.   } ifelse
  314. } bdef
  315. /gsparamdict mark
  316.   /SA { setstrokeadjust }
  317.   /OP { 1 index /op known not { dup op } if OP }
  318.     % The PDF 1.3 specification says that the name /Default is only
  319.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  320.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  321.     % with the older keys, so we have to implement this.
  322.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  323.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  324.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  325.   /HT {
  326.     dup /Default eq {
  327.       pop .setdefaulthalftone
  328.     } {
  329.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  330.       resolvehalftone sethalftone
  331.     } ifelse
  332.     % the transfer function may dependent on the halftone, so make sure
  333.     % it is set if included in the graphic state (otherwise this is
  334.     % subject to order of a dictionary forall, which is unpredictable)
  335.     dup /TR2 .knownget {
  336.       dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse
  337.     } {
  338.       dup /TR .knownget {
  339.         /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse
  340.       } if
  341.     } ifelse
  342.   }
  343.   /HTP {
  344.     % HTP may be present even if this isn't a DPS interpreter.
  345.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  346.   }
  347.     % PDF 1.3
  348.   /Font { aload pop Tf }
  349.   /LW { setlinewidth }
  350.   /LC { setlinecap }
  351.   /LJ { setlinejoin }
  352.   /ML { 1 .max setmiterlimit }
  353.   /D { aload pop setdash }
  354.   /RI { ri }
  355.   /op { op }
  356.   /OPM { OPM }
  357.   /BG2 { gsbg }
  358.   /UCR2 { gsucr }
  359.   /TR2 { gstr }
  360.   /FL { 1 .min setflat }
  361.   /SM {
  362.     % SM may be present even if this is only a Level 2 interpreter.
  363.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  364.   }
  365.     % PDF 1.4
  366.     % All of these require the "transparency" feature in the interpreter.
  367.   /ca { ca }
  368.   /CA { CA }
  369.   /SMask { gssmask }
  370.   /AIS { AIS }
  371.   /BM { BM }
  372.   /TK { TK }
  373. .dicttomark readonly def
  374. /gs {            % <gsres> gs -
  375.   Page /ExtGState rget {
  376.     % We keep the dictionary on the stack during the forall so that
  377.     % keys that interact with each other have access to it.
  378.     dup {
  379.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  380.     } forall pop
  381.   } if
  382. } bdef
  383.  
  384. % ------ Transparency support ------ %
  385.  
  386. /gssmask {
  387.   dup /None eq PDFusingtransparency not or {
  388.     pop null
  389.   } {
  390.     % Preprocess the SMask value into a parameter dictionary for
  391.     % .begintransparencymaskgroup, with added /BBox and /Draw keys.
  392.     mark exch        % Stack: mark smaskdict
  393.     dup /S oget /Subtype exch 3 2 roll
  394.             % Stack: mark ... smaskdict
  395.     dup /BC knownoget {
  396.       dup /Background exch 4 2 roll
  397.       gsave
  398.         1 index /G oget /Group oget /CS knownoget {
  399.       resolvecolorspace dup setgcolorspace csput
  400.     } if
  401.         aload pop setcolor [ currentgray ]
  402.       grestore
  403.       /GrayBackground exch 3 2 roll
  404.     } if
  405.     dup /TR knownoget {
  406.       resolveidfnproc /TransferFunction exch 3 2 roll
  407.     } if    
  408.     dup /G oget dup /BBox oget /BBox exch 4 2 roll
  409.     /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  410.     pop .dicttomark
  411.   } ifelse SMask
  412. } bdef
  413.  
  414. % This procedure is called to actually render the soft mask.
  415. /.execmaskgroup {    % <masknum> <paramdict> <formdict> .execmaskgroup -
  416.     % Save our place in PDFfile, and do a gsave to avoid resetting
  417.     % the color space.
  418.   currentcolorspace 4 1 roll
  419.   PDFfile fileposition 4 1 roll
  420.     % We have to select the group's color space so that the
  421.     % background color will be interpreted correctly.
  422.   dup /Group oget /CS knownoget { resolvecolorspace dup setgcolorspace csput } if
  423.   exch dup /BBox get aload pop .begintransparencymaskgroup {
  424.     dup /Resources knownoget { oforce } { 0 dict } ifelse
  425.     exch false resolvestream
  426.     .execgroup .endtransparencymask
  427.   } stopped {
  428.     .discardtransparencymask stop
  429.   } if
  430.   PDFfile exch setfileposition 
  431.   setcolorspace
  432. } bdef
  433. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  434. /.execgroup {        % <resdict> <stream> .execgroup -
  435.   gsave //nodict begin
  436.   null SMask
  437.   1 .setopacityalpha 1 .setshapealpha
  438.   /Compatible .setblendmode
  439.     % Execute the body of the Form, similar to DoForm.
  440.   pdfopdict .pdfruncontext
  441.   end grestore
  442. } bdef
  443.  
  444. /.beginformgroup {    % groupdict bbox .beginformgroup -
  445.   exch mark exch            % bbox mark groupdict
  446.   dup /CS knownoget { resolvecolorspace setgcolorspace } if
  447.   dup /I knownoget { /Isolated exch 3 2 roll } if
  448.   dup /K knownoget { /Knockout exch 3 2 roll } if
  449.   pop .dicttomark
  450.         % Stack: bbox paramdict
  451.   exch aload pop
  452.   .begintransparencygroup
  453. } bdef
  454.  
  455. % .paintgroupform implements the Form PaintProc in the case where the
  456. % Form XObject dictionary includes a Group key.  See .paintform below.
  457. /.paintgroupform {    % <resdict> <stream> <formdict> .paintgroupform -
  458.   dup /Group oget exch /BBox oget
  459.         % Stack: resdict stream groupdict bbox
  460.   .beginformgroup {
  461.     .execgroup
  462.   } stopped {
  463.     .discardtransparencygroup stop
  464.   } if .endtransparencygroup
  465. } bdef
  466.  
  467. % Make an ImageType 103 (soft-masked) image.
  468. /makesoftmaskimage {    % <datasource> <imagemask> <SMask> makesoftmaskimage
  469.             %   <datasource> <imagemask>, updates currentdict =
  470.             %   imagedict
  471.         % See the ImageType 3 case of makemaskimage below.
  472.         % SMask is a stream, another Image XObject.
  473.         % Stack: datasource imagemask(false) smaskstreamdict
  474.   PDFfile fileposition exch
  475.   dup /Matte knownoget { /Matte exch def } if
  476.   dup length dict makeimagedict pop
  477.         % In order to prevent the two data sources from being
  478.         % aliased, we need to make at least one a reusable stream.
  479.         % We pick the mask, since it's smaller (in case we need to
  480.         % read all its data now).
  481.         % Stack: datasource imagemask(false) savedpos
  482.         % maskdict is currentdict
  483.   /DataSource DataSource mark
  484.     /Intent 1
  485.     /AsyncRead true
  486.   .dicttomark .reusablestreamdecode def
  487.   PDFfile exch setfileposition
  488.   currentdict end currentdict end
  489.   5 dict begin
  490.   /ImageType 103 def
  491.   /DataDict exch def
  492.   dup /InterleaveType 3 put
  493.   DataDict /Matte knownoget {
  494.     /Matte exch def
  495.   } if
  496.   AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  497.   /ColorSpace DataDict /ColorSpace get def
  498. } bdef
  499.  
  500. % ---------------- Color setting ---------------- %
  501.  
  502. /01_1 [0 1] readonly def
  503. /01_3 [0 1 0 1 0 1] readonly def
  504. /01_4 [0 1 0 1 0 1 0 1] readonly def
  505.  
  506. % The keys here are resolved (PostScript, not PDF) color space names.
  507. /csncompdict 8 dict begin
  508.   /DeviceGray { pop 1 } bdef
  509.   /DeviceRGB { pop 3 } bdef
  510.   /DeviceCMYK { pop 4 } bdef
  511.   /CIEBasedA { pop 1 } bdef
  512.   /CIEBasedABC { pop 3 } bdef
  513.   /ICCBased { 1 oget /N oget } bdef
  514.   /Separation { pop 1 } bdef
  515.   /DeviceN { 1 oget length } bdef
  516. currentdict end readonly def
  517.  
  518. /csrdict 13 dict begin 
  519.   /DeviceGray { } bdef
  520.   /DeviceRGB { } bdef
  521.   /DeviceCMYK { } bdef
  522.  
  523.   /CalGray {
  524.     1 oget 6 dict begin
  525.     dup /Gamma knownoget {
  526.       /exp load 2 packedarray cvx /DecodeA exch def
  527.     } if
  528.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  529.     dup /WhitePoint knownoget {
  530.       dup /WhitePoint exch def
  531.       dup /MatrixA exch def
  532.       /RangeLMN [ 3 2 roll { 0 exch } forall ] def
  533.     } if
  534.     /PDFColorSpace exch def [ /CIEBasedA currentdict end ]
  535.   } bdef
  536.  
  537.   /CalRGB {
  538.     1 oget 6 dict begin
  539.     dup /Gamma knownoget {
  540.       [ exch { /exp load 2 packedarray cvx } forall
  541.       ] /DecodeABC exch def
  542.     } if
  543.     dup /Matrix knownoget { /MatrixABC exch def } if
  544.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  545.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  546.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  547.   } bdef
  548.  
  549.   /CalCMYK {
  550.     pop /DeviceCMYK        % not defined by Adobe
  551.   } bdef
  552.  
  553.   /Lab {
  554.     1 oget 6 dict begin
  555.     dup /Range knownoget not { [-100 100 -100 100] } if
  556.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  557.     /RangeABC exch def
  558.     /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def
  559.     /MatrixABC [1 1 1 1 0 0 0 0 -1] def
  560.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  561.     dup /WhitePoint knownoget { /WhitePoint exch def } {
  562.       (   **** Warning: Lab colorspace is missing WhitePoint.\n)
  563.       pdfformaterror
  564.       /WhitePoint [0.9505 1 1.089] def
  565.     } ifelse
  566.     % scaling function g() for DecodeLMN construction
  567.     { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse }
  568.     /DecodeLMN [
  569.       % Store white point implicitly inside procedures.
  570.       [ 3 index aload pop WhitePoint 0 get /mul .systemvar ] cvx bind
  571.       [ 4 index aload pop WhitePoint 1 get /mul .systemvar ] cvx bind
  572.       [ 5 index aload pop WhitePoint 2 get /mul .systemvar ] cvx bind
  573.     ] def pop
  574.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  575.   } bdef
  576.  
  577.   /ICCBased {
  578.     dup 1 get type /dicttype ne {    % don't resolve more than once
  579.     PDFfile fileposition exch
  580.     dup dup 1 oget
  581.     mark exch { oforce } forall .dicttomark
  582.     dup dup true resolvestream
  583.     /ReusableStreamDecode filter /DataSource exch put
  584.     1 exch put
  585.     exch PDFfile exch setfileposition
  586.     % Resolve alternate color space
  587.     dup 1 get            % Get colorspace dictionary
  588.     dup /Alternate .knownget    % Check for alternate color space
  589.     { oforce resolvecolorspace /Alternate exch put }    % resolve and replace
  590.     { pop }            % remove colorspace dictionary
  591.     ifelse
  592.     } if
  593.   } bdef
  594.  
  595.   /Separation {
  596.     aload pop exch oforce resolvecolorspace
  597.                 % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01
  598.                 % can use /Identity name here instead of a function.
  599.     exch oforce resolveidfnproc
  600.     4 array astore
  601.   } bdef
  602.  
  603.   /DeviceN {
  604.     [ exch aload pop ]            % Copy into a new array
  605.     dup dup 1 oget            % Resolve Names array
  606.     [ exch { oforce } forall ]        % resolve each of the names
  607.     1 exch put
  608.     dup dup 2 oget resolvecolorspace
  609.     2 exch put
  610.     dup dup 3 oget resolvefnproc
  611.     3 exch put
  612.     dup length 4 gt {            % Check for attributes dict
  613.       dup dup 4 oget            % devn_array devn_array attr_dict
  614.       dup /Colorants knownoget        % Check for Colorants Dict
  615.     {    % Create a new attribute dict with only a Colorants dict entry.
  616.         % Resolve all of the Colorant dict entries.  This is needed
  617.         % to prevent a conflict if we attempt to resolve the tint
  618.         % transform functions of the Colorant color spaces multiple
  619.         % times.
  620.       exch pop            % Remove old attributes dict
  621.       << exch            % Start new attributes dict
  622.           % Build new Colorants dict with resolved entries
  623.       << exch { oforce resolvecolorspace } forall >>
  624.              /Colorants exch >>        % Finish new attributes dict
  625.      } if
  626.       4 exch put            % Put resolved or new attributes dict
  627.     } if
  628.   } bdef
  629.  
  630.   /Indexed {
  631.     aload pop 3 -1 roll oforce resolvecolorspace
  632.         % Stack: /Indexed hival lookup basespace
  633.         % If the underlying space is a Lab space, we must scale
  634.         % the output of the lookup table as part of DecodeABC.
  635.     dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  636.       dup 1 get /DecodeLMN known {
  637.     1 get dup length dict copy
  638.     begin /DecodeABC [ 0 2 4 {
  639.       RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  640.       RangeABC 3 index get /add load
  641.       DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  642.     } for ] def
  643.     /RangeABC //01_3 def
  644.     currentdict end /CIEBasedABC exch 2 array astore
  645.       } if
  646.     } if
  647.     3 1 roll
  648.     oforce dup type /stringtype ne {
  649.         % The color lookup table is a stream.
  650.         % Get its contents.  Don't lose our place in PDFfile.
  651.         % Stack: /Indexed basespace hival lookup
  652.     PDFfile fileposition 5 1 roll true resolvestream
  653.         % Stack: filepos /Indexed basespace hival lookupstream
  654.     1 index 1 add
  655.         % Stack: filepos /Indexed basespace hival lookupstream len
  656.     3 index
  657.       dup dup type /arraytype eq { 0 get } if
  658.       //csncompdict exch get exec mul
  659.     string dup 3 1 roll readstring pop  % the string is padded with 0s
  660.         length 1 index length lt {
  661.           (   **** Warning: Short look-up table in the Indexed color space was padded with 0's.\n)
  662.           pdfformaterror
  663.         } if
  664.         % Stack: filepos /Indexed basespace hival table table'
  665.     5 -1 roll PDFfile exch setfileposition
  666.     }
  667.     if 4 array astore
  668.         % Replace the PDFColorSpace with the Indexed space if needed.
  669.     dup 1 get
  670.     dup type /arraytype eq {
  671.       dup length 2 ge {
  672.     dup 1 get type /dicttype eq {
  673.       dup 1 get /PDFColorSpace known {
  674.         dup 1 get /PDFColorSpace 3 index put
  675.       } if
  676.     } if
  677.       } if
  678.     } if pop
  679.   } bdef
  680.  
  681.   /I { % Bug 689815
  682.     (   **** Warning: The name /Indexed cannot be abbreviated to /I in the color space\n)
  683.     pdfformaterror
  684.     dup 0 /Indexed put
  685.     //Indexed exec 
  686.   } bdef
  687.  
  688.   /Pattern {
  689.     dup type /nametype ne {
  690.       dup length 1 gt {
  691.     1 oget resolvecolorspace
  692.     /Pattern exch 2 array astore
  693.       } if
  694.     } if
  695.   } bdef
  696.  
  697. currentdict end readonly def
  698.  
  699. /cssubst {        % <csname> cssubst <cspace'> true
  700.             % <csname> cssubst false
  701.   dup resolvecolorspace
  702.   dup 1 index ne { exch pop true } { pop pop false } ifelse
  703. } bdef
  704.  
  705. /csnames mark
  706.   /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
  707. .dicttomark readonly def
  708. /csresolve {        % <csresourcename> csresolve <cspace>
  709.   dup type /nametype ne {
  710.     (\n   **** Warning: CS/cs (setcolorspace) operand not a name: ) pdfformaterror
  711.     dup stderrfile dup 3 -1 roll write==only flushfile
  712.     ( ****\n) pdfformaterror
  713.     dup type /arraytype eq {    % Adobe InDesign + PDF Library has array
  714.       resolvecolorspace
  715.     } if
  716.   } {
  717.     dup Page /ColorSpace rget {
  718.       exch pop resolvecolorspace
  719.     } {
  720.       //csnames 1 index known not { /undefined cvx signalerror } if
  721.     } ifelse
  722.   } ifelse
  723. } bdef
  724. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  725.   dup dup type /arraytype eq { 0 get } if
  726.   //csrdict exch .knownget
  727.   {
  728.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  729.   } {
  730.     dup type /nametype eq { csresolve } { csset exch pop } ifelse
  731.   } ifelse
  732. } bdef
  733.  
  734. /scresolve {    % <c0> ... scresolve <multi>
  735.         % We can't really make sc[n] and SC[N] work, because
  736.         % the color space information isn't available at
  737.         % conversion time; so we hack it by assuming that
  738.         % all the operands on the stack are used, and that
  739.         % if the top operand is a name, it's a Pattern resource.
  740.   dup type /nametype eq
  741.     { Page /Pattern rget { resolvepattern } { null } ifelse }
  742.   if
  743.   dup type /dicttype eq {
  744.         % Check the PaintType, if any (shading patterns don't
  745.         % have one).
  746.     dup /PaintType knownoget { 2 eq } { false } ifelse
  747.   } {
  748.     .pdfcount 1 gt
  749.   } ifelse
  750. } bdef
  751.  
  752. /.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  753.   PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Begin PaintProc) print dup === flush } if } if
  754.     % For uncolored patterns, we have to unbind the current
  755.     % color and color space before running the PaintProc.
  756.     % There's no harm in doing this for colored patterns,
  757.     % so for simplicity, we always do it.
  758.   PDFfile fileposition 3 1 roll
  759.   q
  760.   //null sc1 //null SC1
  761.  
  762.   % Save old values on opstack, set pdfemptycount to new value.
  763.   pdfemptycount countdictstack
  764.   /pdfemptycount count 3 sub def 4 2 roll
  765.   %
  766.   % Stack: ... <old emptycount> <dictcount> <patdict> <resdict> 
  767.   %                                            |
  768.   %           New empty count points here -----+
  769.  
  770.   exch //false resolvestream pdfopdict .pdfruncontext
  771.  
  772.   countdictstack exch sub dup 0 gt { 
  773.      (   **** Warning: Pattern stream has imbalanced q/Q operators (too many q's)\n)
  774.      pdfformaterror
  775.      { Q } repeat
  776.    } {
  777.      pop
  778.    } ifelse
  779.  
  780.   % restore pdfemptycount
  781.   /pdfemptycount exch def
  782.  
  783.   Q
  784.   PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if
  785.   PDFfile exch setfileposition
  786. } bdef
  787.  
  788. /resolvepattern {    % <patternstreamdict> resolvepattern <patterndict>
  789.         % Don't do the resolvestream now: just capture the data
  790.         % from the file if necessary.
  791.   dup length dict copy
  792.   dup /FilePosition .knownget {
  793.     1 index /File get dup fileposition 3 1 roll
  794.         % Stack: dict savepos pos file
  795.     dup 3 -1 roll setfileposition
  796.     dup 3 index /Length oget
  797.  
  798.     dup 65535 le {
  799.       dup 0 eq {
  800.         pop pop ()
  801.       } {
  802.         string readstring pop
  803.       } ifelse
  804.     } {
  805.       () /SubFileDecode filter /ReusableStreamDecode filter
  806.     } ifelse
  807.         % Stack: dict savepos file string
  808.     3 1 roll exch setfileposition
  809.     1 index /File 3 -1 roll put
  810.     dup /FilePosition undef
  811.   } if
  812.   dup /Shading knownoget {
  813.     resolveshading 1 index /Shading 3 -1 roll put
  814.   } if
  815.   dup /PaintProc [
  816.         % Bind the resource dictionary into the PaintProc.
  817.     2 index /Resources knownoget { oforce } { 0 dict } ifelse
  818.     /.pdfpaintproc cvx
  819.   ] cvx put
  820.   PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Pattern: ) print dup === flush } if } if
  821. } bdef
  822.  
  823. /ignore_color_op  (   **** Warning: Ignoring a color operation in a cached context.\n) readonly def
  824.  
  825. drawopdict begin
  826.   /g  { .incachedevice { % Bug 689302
  827.           pop //ignore_color_op pdfformaterror
  828.         } {
  829.           /DeviceGray cssubst { cs sc1 } { g } ifelse
  830.         } ifelse
  831.       } bdef
  832.  
  833.   /rg { .incachedevice {
  834.           pop pop pop //ignore_color_op pdfformaterror
  835.         } {
  836.           /DeviceRGB cssubst { cs sc* } { rg } ifelse
  837.         } ifelse
  838.       } bdef
  839.  
  840.   /k  { .incachedevice {
  841.           pop pop pop pop //ignore_color_op pdfformaterror
  842.         } {
  843.           k
  844.         } ifelse
  845.       } bdef
  846.  
  847.   /cs { .incachedevice {
  848.           pop //ignore_color_op pdfformaterror
  849.         } {
  850.           csresolve cs
  851.         } ifelse
  852.       } bdef
  853.  
  854.   /sc { .incachedevice {
  855.           .pdfcount { pop } repeat //ignore_color_op pdfformaterror
  856.         } {
  857.           scresolve { sc* } { sc1 } ifelse
  858.         } ifelse
  859.       } bdef
  860.  
  861.   /scn /sc load def
  862.  
  863.   /G  { .incachedevice {
  864.           pop //ignore_color_op pdfformaterror
  865.         } {
  866.           /DeviceGray cssubst { CS SC1 } { G } ifelse
  867.         } ifelse
  868.       } bdef
  869.  
  870.   /RG { .incachedevice {
  871.           pop pop pop //ignore_color_op pdfformaterror
  872.         } {
  873.           /DeviceRGB cssubst { CS SC* } { RG } ifelse
  874.         } ifelse
  875.       } bdef
  876.  
  877.   /K  { .incachedevice {
  878.           pop pop pop pop //ignore_color_op pdfformaterror
  879.         } {
  880.           K
  881.         } ifelse
  882.       } bdef
  883.  
  884.   /CS { .incachedevice {
  885.           pop //ignore_color_op pdfformaterror
  886.         } {
  887.           csresolve CS
  888.         } ifelse
  889.       } bdef
  890.  
  891.   /ri { .incachedevice {
  892.           pop //ignore_color_op pdfformaterror
  893.         } {
  894.           ri
  895.         } ifelse
  896.       } bdef
  897.  
  898.   /SC { .incachedevice {
  899.           .pdfcount { pop } repeat //ignore_color_op pdfformaterror
  900.         } {
  901.           scresolve { SC* } { SC1 } ifelse
  902.         } ifelse
  903.       } bdef
  904.  
  905.   /SCN /SC load def
  906. end
  907.  
  908. currentdict /ignore_color_op undef
  909.  
  910. % ---------------- Paths ---------------- %
  911.  
  912. drawopdict begin
  913.             % Path construction
  914.   /m /moveto load def
  915.   /l /lineto load def
  916.   /c /curveto load def
  917.   /v { currentpoint 6 2 roll curveto } def
  918.   /y { 2 copy curveto } def
  919.   /re {
  920.    4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
  921.    closepath
  922.   } def
  923.   /h /closepath load def
  924.             % Path painting and clipping
  925.   /n { n } def
  926.   /S { S } def
  927.   /s { s } def
  928.   /f { f } def
  929.   /f* { f* } def
  930.   /B { B } def
  931.   /b { b } def
  932.   /B* { B* } def
  933.   /b* { b* } def
  934.   /W { W } def
  935.   /W* { W* } def
  936.   /sh { setfillstate resolvesh 
  937.         gsave 0 .setoverprintmode 
  938.         dup /.shading .knownget {
  939.           exch 
  940.           pop
  941.         } {
  942.           dup
  943.           .buildshading
  944.           dup 3 1 roll /.shading exch put
  945.         } ifelse
  946.         .shfill grestore 
  947.       } def
  948. end
  949.  
  950. % ---------------- XObjects ---------------- %
  951.  
  952. /xobjectprocs mark        % <dict> -proc- -
  953.   /Image { DoImage }
  954.   /Form { DoForm }
  955.   /PS { DoPS }
  956. .dicttomark readonly def
  957.  
  958. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  959. % color space names.
  960. /defaultdecodedict mark
  961.   /DeviceGray { pop //01_1 } bind
  962.   /DeviceRGB { pop //01_3 } bind
  963.   /DeviceCMYK { pop //01_4 } bind
  964.   /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind
  965.   /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
  966.   /ICCBased {
  967.      1 oget dup /Range knownoget {
  968.        exch pop
  969.      }{
  970.        /N get [ exch {0 1} repeat ] readonly
  971.      } ifelse
  972.   } bind
  973.   /Separation { pop //01_1 } bind
  974.   /DeviceN {
  975.     1 oget length [ exch {0 1} repeat ] readonly
  976.   } bind
  977.   /Indexed {
  978.     pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  979.   } bind
  980. .dicttomark readonly def
  981.  
  982. /checkaltimage {    % <resdict> checkaltimage <resdict[']>
  983.   Printed {
  984.     dup /Alternates knownoget {
  985.       {
  986.     dup /DefaultForPrinting knownoget {
  987.       {
  988.         /Image oget exch pop exit
  989.       } {
  990.         pop
  991.       } ifelse
  992.     } {
  993.       pop
  994.     } ifelse
  995.       } forall
  996.     } if
  997.   } if
  998. } bdef
  999.  
  1000. /makeimagedict {    % <resdict> <newdict> makeimagedict <imagemask>
  1001.             % On return, newdict' is currentdict
  1002.   begin
  1003.   /Width 2 copy oget def
  1004.   /Height 2 copy oget def
  1005.         % Handle missing BitsPerComponent later.
  1006.   /BitsPerComponent 2 copy knownoget { def } { pop } ifelse
  1007.   /Interpolate 2 copy knownoget { def } { pop } ifelse
  1008.   makeimagekeys
  1009. } bdef
  1010. /makeimagekeys {    % <resdict> makeimagekeys <imagemask>
  1011.         % newdict is currentdict
  1012.         % Assumes Width, Height, BPC, Interpolate already copied.
  1013.   /ImageType 1 def
  1014.   /ImageMatrix Width 0 0
  1015.         % Handle 0-height images specially.
  1016.     Height dup 0 eq { pop 1 } if neg 0 1 index neg
  1017.     6 array astore def
  1018.   dup /ImageMask knownoget dup { and } if {
  1019.         % Image mask
  1020.         % Decode is required for the PostScript image operators.
  1021.                 % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
  1022.     /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
  1023.         % BitsPerComponent is optional for masks.
  1024.     /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  1025.     true
  1026.   } {
  1027.         % Opaque image
  1028.     dup /ColorSpace knownoget 
  1029.     % JPXDecode filters can omit the /ColorSpace and /BitsPerComponent
  1030.     % keys, in which case the interpreter must retrieve this information
  1031.     % from inside the compressed stream. Here we substitute the most
  1032.     % likely values as a work-around.
  1033.     not {
  1034.       (   **** Warning: assuming JPX image is 8-bit RGB.\n) stderrprint
  1035.       [/DeviceRGB] /BitsPerComponent 8 def
  1036.     } if 
  1037.     resolvecolorspace /ColorSpace exch def
  1038.         % Decode is required for the PostScript image operators.
  1039.     /Decode 2 copy knownoget not {
  1040.       ColorSpace //defaultdecodedict
  1041.       ColorSpace dup type /arraytype eq { 0 get } if get exec
  1042.     } if def
  1043.     false
  1044.   } ifelse
  1045.         % Even though we're going to read data,
  1046.         % pass false to resolvestream so that
  1047.         % it doesn't try to use Length (which may not be present).
  1048.   exch false resolvestream /DataSource exch def
  1049. } bdef
  1050.  
  1051. /DoImage {
  1052.   checkaltimage dup length 6 add dict
  1053.   1 index /SMask knownoget { 1 index exch /SMask exch put } if
  1054.   1 index /Mask knownoget { 1 index exch /Mask exch put } if
  1055.   makeimagedict doimagesmask
  1056. } bdef
  1057. /makemaskimage {    % <datasource> <imagemask> <Mask> makemaskimage
  1058.             %   <datasource> <imagemask>, updates currentdict =
  1059.             %   imagedict
  1060.   dup type /arraytype eq {
  1061.     /ImageType 4 def
  1062.                 % Check that every element of the Mask is an integer.
  1063.     //false 1 index {
  1064.       type /integertype ne or
  1065.     } forall {
  1066.       (\n   **** Warning: Some elements of Mask array are not integers.\n)
  1067.       pdfformaterror
  1068.       [ exch { 0.5 add cvi } forall ]  % following AR4, 5, 6 implementation
  1069.     } if
  1070.     % Check elements of array are within 0::(2**BitsPerComponent)-1
  1071.     % This is a PostScript error, but AR ignores Mask in that case
  1072.     1 BitsPerComponent bitshift 1 sub //false 2 index {
  1073.       % stack: max_value result_bool value
  1074.       dup 0 lt exch 3 index gt or or
  1075.     } forall exch pop {
  1076.       (\n   **** Warning: Some elements of Mask array are out of range.\n)
  1077.       pdfformaterror
  1078.       [ exch { 0 .max 1 BitsPerComponent bitshift 1 sub .min } forall ]
  1079.     } if
  1080.     /MaskColor exch def
  1081.   } {
  1082.         % Mask is a stream, another Image XObject.
  1083.         % Stack: datasource imagemask(false) maskstreamdict
  1084.     PDFfile fileposition exch
  1085.     dup length dict makeimagedict pop
  1086.         % In order to prevent the two data sources from being
  1087.         % aliased, we need to make at least one a reusable stream.
  1088.         % We pick the mask, since it's smaller (in case we need to
  1089.         % read all its data now).
  1090.         % Stack: datasource imagemask(false) savedpos
  1091.         % maskdict is currentdict
  1092.     /DataSource DataSource mark
  1093.       /Intent 1
  1094.       /AsyncRead true
  1095.     .dicttomark .reusablestreamdecode def
  1096.     PDFfile exch setfileposition
  1097.     currentdict end currentdict end
  1098.     5 dict begin
  1099.     /ImageType 3 def
  1100.     /InterleaveType 3 def
  1101.     /DataDict exch def
  1102.     /MaskDict exch def
  1103.     /ColorSpace DataDict /ColorSpace get def
  1104.   } ifelse
  1105. } bdef
  1106.  
  1107. /doimagesmask { % <imagemask> doimagesmask -
  1108.   PDFusingtransparency { currentdict /SMask knownoget } { false } ifelse {
  1109.     .begintransparencymaskimage
  1110.     PDFfile fileposition exch
  1111.     gsave //nodict begin
  1112.     null /SoftMask gput
  1113.     1 .setopacityalpha 1 .setshapealpha
  1114.     /Compatible .setblendmode
  1115.     DoImage
  1116.     end grestore
  1117.     PDFfile exch setfileposition
  1118.     0 .endtransparencymask
  1119.     << /Subtype /Group /Isolated true 
  1120.       /.image_with_SMask true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c 
  1121.     >> 0 0 1 1 .begintransparencygroup
  1122.     doimage
  1123.     .endtransparencygroup
  1124.   } {
  1125.     doimage
  1126.   } ifelse
  1127. } bdef
  1128.  
  1129. % For development needs we define a special option for running with a new handler
  1130. % for images with a soft mask.
  1131. //systemdict /NEW_IMAGE3X .knownget not { //false } if {
  1132.   /doimagesmask { % <imagemask> doimagesmask -
  1133.     doimage
  1134.   } bdef
  1135. } if
  1136.  
  1137. /is_big_mask {  % - is_big_mask <bool>
  1138.   1 0 dtransform dup mul exch dup mul sqrt add
  1139.   0 1 dtransform dup mul exch dup mul sqrt add mul
  1140.   currentdevice getdeviceprops .dicttomark /BufferSpace .knownget not {
  1141.     4000000 % hack: Can't get the real default value from C source.
  1142.   } if
  1143.   2 % arbitrary
  1144.   div gt
  1145. } bind def
  1146.  
  1147. % For development needs we define a special option for running with a new handler
  1148. % for images with a soft mask.
  1149. //systemdict /NEW_IMAGE3X .knownget not { //false } if {
  1150.   /is_big_mask {  % - is_big_mask <bool>
  1151.     //false
  1152.   } bdef
  1153. } if
  1154.  
  1155. /doimage {    % <imagemask> doimage -
  1156.         % imagedict is currentdict, gets popped from dstack
  1157.   DataSource exch
  1158.   PDFusingtransparency
  1159.   currentdevice .devicename /pdfwrite ne { 
  1160.     % This is a temporary workaround for the bug 689080,
  1161.     % which is done under a rush of 8.63 release.
  1162.     % The purpose is to disable a conversion of an image with soft mask
  1163.     % into a Type 103 image, which currently allocates a full mask buffer
  1164.     % before writing clist. Note that imagemask installs
  1165.     % the transparency mask anyway (likely another bug), 
  1166.     % so the image is still masked.
  1167.     % With this workaround the Matte color is not working (ignored).
  1168.     is_big_mask not 
  1169.   } {
  1170.     true % pdfwrite doesn't need the workaround explained above,
  1171.          % and cannot work with it. 
  1172.   } ifelse
  1173.   and {
  1174.     currentdict /SMask knownoget
  1175.   } {
  1176.     false
  1177.   } ifelse {
  1178.     makesoftmaskimage
  1179.   } {
  1180.     currentdict /Mask knownoget {
  1181.       makemaskimage
  1182.     } if
  1183.   } ifelse
  1184.         % Stack: datasource imagemask
  1185.    { currentdict end setfillstate { imagemask } }
  1186.    { ColorSpace setgcolorspace currentdict end setfillblend { image } }
  1187.   ifelse
  1188.   stopped {
  1189.     dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack
  1190.     $error /errorname get dup /ioerror eq {
  1191.       pop (\n   **** Warning: File has insufficient data for an image.\n)
  1192.       pdfformaterror
  1193.     } {
  1194.       (\n   **** Warning: File encountered ')
  1195.       exch 40 string cvs concatstrings
  1196.       (' error while processing an image.\n) concatstrings
  1197.       pdfformaterror
  1198.     } ifelse
  1199.   } if
  1200.         % Close the input stream, unless it is PDFfile or
  1201.         % PDFsource.
  1202.   dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  1203. } bdef
  1204.  
  1205. /.paintform {    % <formdict> <resdict> <stream> .paintform -
  1206.   3 -1 roll dup /Group known PDFusingtransparency and {
  1207.     .paintgroupform
  1208.   } {
  1209.     pop pdfopdict .pdfruncontext
  1210.   } ifelse
  1211. } bdef
  1212.  
  1213. /DoForm {
  1214.     % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  1215.     % and /Matrix keys optional. Cope with the missing keys.
  1216.   begin <<
  1217.   currentdict /FormType known not { /FormType 1 } if
  1218.   currentdict /Matrix   known not { /Matrix { 1 0 0 1 0 0 } cvlit } if
  1219.   currentdict end { oforce } forall
  1220.   >>
  1221.   dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  1222.   3 index false /resolvestream cvx
  1223.   /.paintform cvx
  1224.   ] cvx /PaintProc exch put
  1225.     % Adjust pdfemptycount since we have an extra dictionary on the stack
  1226.   pdfemptycount exch
  1227.   /pdfemptycount where pop count 2 sub /pdfemptycount exch put
  1228.   q execform Q            % gsave / grestore around the Form
  1229.     % Restore pdfemptycount
  1230.   /pdfemptycount where pop exch /pdfemptycount exch put
  1231. } bdef
  1232.  
  1233. /_dops_save 1 array def
  1234.  
  1235. /DoPS {
  1236.   DOPS
  1237.    {
  1238.      //_dops_save 0 save put
  1239.      true resolvestream cvx exec
  1240.      //_dops_save 0 get restore
  1241.    }
  1242.    { pop }
  1243.   ifelse
  1244. } bdef
  1245.  
  1246. currentdict /_dops_save undef
  1247.  
  1248. drawopdict begin
  1249.   /Do {
  1250.     setfillblend
  1251.     PDFfile fileposition exch
  1252.     dup Page /XObject rget { 
  1253.       exch pop dup /Subtype get xobjectprocs exch get
  1254.         % Don't leave extra objects on the stack while executing
  1255.         % the definition of the form.
  1256.       3 -1 roll 2 .execn
  1257.     } {
  1258.         % This should cause an error, but Acrobat Reader can
  1259.         % continue, so we do too.
  1260.       (   **** Undefined XObject resource: ) 
  1261.       exch =string cvs concatstrings (\n) concatstrings
  1262.       pdfformaterror
  1263.     } ifelse
  1264.     PDFfile exch setfileposition
  1265.   } bdef
  1266. end
  1267.  
  1268. % ---------------- In-line images ---------------- %
  1269.  
  1270. % Undo the abbreviations in an in-line image dictionary.
  1271. % Note that we must look inside array values.
  1272. % /I is context-dependent.
  1273. /unabbrevkeydict mark
  1274.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  1275.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  1276. .dicttomark readonly def
  1277. /unabbrevvaluedict mark
  1278.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  1279.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  1280.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  1281.   /G /DeviceGray  /RGB /DeviceRGB
  1282.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  1283. .dicttomark readonly def
  1284. /unabbrevtypedict mark
  1285.   /nametype {
  1286.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  1287.   }
  1288.   /arraytype {
  1289.     dup 0 1 2 index length 1 sub {
  1290.       2 copy get unabbrevvalue put dup
  1291.     } for pop
  1292.   }
  1293. .dicttomark readonly def
  1294. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  1295.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  1296. } bdef
  1297.  
  1298. drawopdict begin
  1299.   /BI { mark } bdef
  1300.   /ID {
  1301.     counttomark 2 idiv dup 7 add dict begin {
  1302.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  1303.       exch unabbrevvalue def
  1304.     } repeat pop
  1305.     /IDFlag true def  % flag for stream processing.
  1306.     /File PDFsource def
  1307.     currentdict makeimagekeys doimage    
  1308.     % The Adobe documentation says that the data following ID
  1309.     % consists of "lines", and some PDF files (specifically, some files
  1310.     % produced by PCL2PDF from Visual Software) contain garbage bytes
  1311.     % between the last byte of valid data and an EOL.
  1312.         % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  1313.         % the stream. Some have no EOL and garbage bytes.
  1314.         % Therefore, we skip all bytes before EI or EOL 
  1315.     0
  1316.       { PDFsource read not { //true exit } if
  1317.         dup 10 eq 1 index 13 eq or
  1318.           { pop PDFsource token pop /EI ne exit
  1319.           }
  1320.         if
  1321.         exch 69 eq 1 index 73 eq and { //false exit } if  % 'EI'
  1322.       }
  1323.     loop
  1324.     exch pop
  1325.       { /ID cvx /syntaxerror signalerror
  1326.       }
  1327.     if
  1328.   } bdef
  1329. end
  1330.  
  1331. % ================================ Text ================================ %
  1332.  
  1333. drawopdict begin
  1334.             % Text control
  1335.   /BT { BT } def
  1336.   /ET { ET } def
  1337.   /Tc { Tc } def
  1338.   /TL { TL } def
  1339.   /Tr { Tr } def
  1340.   /Ts { Ts } def
  1341.   /Tw { Tw } def
  1342.   /Tz { Tz } def
  1343.             % Text positioning
  1344.   /Td { Td } def
  1345.   /TD { TD } def
  1346.   /Tm { Tm } def
  1347.   /T* { T* } def
  1348.             % Text painting
  1349.   /Tj { Tj } def
  1350.   /' { ' } def
  1351.   /" { " } def
  1352.   /TJ { TJ } def
  1353.  
  1354.   /Tform { Tform } def  % Text formatting and painting for AcroForm
  1355.                         % without appearance streams.
  1356.   /QBT {
  1357.     Q BT
  1358.     (   **** Warning: invalid operator QBT processed as Q BT .\n)
  1359.     pdfformaterror  % Bug 690089
  1360.   } def
  1361.  
  1362. end
  1363.  
  1364. % ============================== Annotations ============================== %
  1365.  
  1366.  
  1367.  
  1368. % Get and normalize an annotation's rectangle.
  1369. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  1370.   /Rect oget aload pop
  1371.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  1372.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  1373. } bdef
  1374.  
  1375. % Set an annotation color.
  1376. /annotsetcolor {    % <annot> annotsetcolor -
  1377.   /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1378. } bdef
  1379.  
  1380. % Draw the border.  Currently, we ignore requests for beveling, and we
  1381. % don't round the corners of rectangles.
  1382. /strokeborder {        % <annot> <width> <dash> strokeborder -
  1383.   1 index 0 ne {    % do not draw if border width is 0
  1384.     gsave
  1385.     2 index annotsetcolor
  1386.     0 setdash dup setlinewidth
  1387.     exch annotrect
  1388.     2 { 4 index sub 4 1 roll } repeat
  1389.     2 { 4 index 0.5 mul add 4 1 roll } repeat
  1390.     rectstroke pop
  1391.     grestore
  1392.   } {
  1393.     pop pop pop
  1394.   } ifelse
  1395. } bdef
  1396.  
  1397. % Draw an annotation border.
  1398. /drawborder {        % <annot> drawborder -
  1399.   gsave
  1400.   dup /BS known 1 index /Border known or {
  1401.   dup /BS knownoget {
  1402.       dup type /dicttype ne   % <annot> <border> <bad?>
  1403.     } {
  1404.       dup /Border oget 
  1405.       dup type /arraytype ne  % <annot> [border] <bad?>
  1406.     } ifelse
  1407.     { 
  1408.       (   **** Warning: Wrong type of annotation border object.\n)
  1409.       pdfformaterror
  1410.     } if
  1411.     dup type /dicttype eq {
  1412.     dup /W knownoget not { 1 } if
  1413.       % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is
  1414.       % expressed in points (an absolute unit), so compensate here for any
  1415.       % scaling of the PostScript user space done due to /UserUnit.
  1416.       % Scaling due to -dPDFFitPage is not undone, to keep the correct border width
  1417.       % compared to the size of the surrounding marks.
  1418.       //systemdict /NoUserUnit .knownget not { false } if not
  1419.       //systemdict /PDFFitPage known not and {    % UserUnit is ignored if -dPDFFitPage
  1420.         Page /UserUnit knownoget { div } if
  1421.       } if
  1422.     [] 2 index /S knownoget {
  1423.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1424.     } if 3 -1 roll pop strokeborder
  1425.   } {
  1426.       dup 2 get
  1427.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  1428.       strokeborder
  1429.     } ifelse
  1430.     } {
  1431.       1 [] strokeborder
  1432.     } ifelse
  1433.   grestore
  1434. } bdef
  1435.  
  1436. %
  1437. %   The PDF annotation F (flags) integer is bit encoded.
  1438. %   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
  1439. %         Note:  We have no handlers but we ignore this bit.
  1440. %   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
  1441. %   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
  1442. %         (and not hidden) and Printed is true
  1443. %   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
  1444. %   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
  1445. %   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
  1446. %         if this bit is not set (and not hidden) and Printed is false
  1447. %   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
  1448. %
  1449. /annotvisible {            % <annot> annotvisible <visible>
  1450.   /F knownoget not { 0 } if         % Get flag value
  1451.   dup 2 and 0 eq              % Check hidden flag
  1452.   exch dup 4 and 0 ne Printed and    % Check print flag
  1453.   exch 32 and 0 eq Printed not and    % Check noview flag
  1454.   or                    % Combine print and view
  1455.   and                     % Combine with 'hidden' flag test
  1456. } bdef
  1457.  
  1458. /drawwidget {            % <scalefactor_x> <scalefactor_y> <annot> drawwidget -
  1459.   dup /AP knownoget {
  1460.     dup /N known not {
  1461.       (   **** Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n)
  1462.       pdfformaterror
  1463.     } if
  1464.     //false
  1465.     [/N /R /D] {
  1466.     % stack: scalex scaley annot appearance false key
  1467.       2 index exch knownogetdict {
  1468.     exch not exit 
  1469.       } if
  1470.     } forall
  1471.     % stack: scalex scaley annot appearance value true
  1472.     % stack: scalex scaley annot appearance false
  1473.     dup {
  1474.       pop exch pop
  1475.         % Acrobat Distiller produces files in which this Form
  1476.         % XObject lacks Type and Subtype keys.  This is illegal,
  1477.         % but Acrobat Reader accepts it.  The only way we can
  1478.         % tell whether this is a Form or a set of sub-appearances
  1479.         % is by testing for the stream Length or File key.
  1480.                 % If the stream lacks Length key, try File key.
  1481.       dup /Length known 1 index /File known or {
  1482.               % If this is a form then simply use it
  1483.         //true
  1484.       } {
  1485.         1 index /AS knownoget not {
  1486.               % If we do not have AS then use any appearance
  1487.         { exch pop oforce exit } forall //true
  1488.         } { 
  1489.         % Stack: annot Ndict AS
  1490.         % Get the specified appearance.  If no appearance, then
  1491.         % display nothing - set stack = false.
  1492.       knownoget
  1493.         } ifelse
  1494.       } ifelse
  1495.     } {
  1496.       exch pop    % discard useless AP dictionary
  1497.     } ifelse
  1498.  
  1499.         % Stack: scalex scaley annot appearance true
  1500.         % Stack: scalex scaley annot false
  1501.     {
  1502.               % Draw appearance
  1503.                 % Initialize graphic following "7.4.4 Appearance Streams"
  1504.       q graphicsbeginpage textbeginpage
  1505.       1 index annotrect pop pop translate
  1506.       3 index 3 index scale    % Apply scale factors
  1507.       dup /BBox knownoget {
  1508.         1 index /Matrix knownoget not { {1 0 0 1 0 0} } if
  1509.         .bbox_transform pop pop
  1510.         % Compensate for non-zero origin of BBox
  1511.         neg exch neg exch translate
  1512.       } if
  1513.       DoForm Q
  1514.     } if
  1515.   } {
  1516.     dup /FT knownoget {
  1517.       /Tx eq {
  1518.       % Stack: scalex scaley annot
  1519.     dup /DA known 1 index /V known and {
  1520.       dup /DA oget
  1521.       q graphicsbeginpage textbeginpage
  1522.       1 index annotrect pop pop translate
  1523.       3 index 3 index scale        % Apply scale factors
  1524.       cvx exec
  1525.       dup /V oget
  1526.       0 0 moveto dup false charpath pathbbox newpath 3 -1 roll
  1527.       sub abs 3 1 roll sub abs
  1528.       3 index annotrect 4 2 roll pop pop
  1529.       6 index mul exch 6 index mul
  1530.         % stack: scale annot V vsize hsize vrect hrect
  1531.       % Calculate horizontal justification first
  1532.       % horizontal can be left (Q=0), center (Q=1), or right (Q=2) justification
  1533.       3 -1 roll 
  1534.         % stack: scalex scaley annot V vsize vrect hrect hsize 
  1535.       5 index /Q knownoget not { 0 } if    % default 0 == left
  1536.       dup 0 eq {
  1537.           pop pop pop 0        % left justified
  1538.         } {
  1539.         1 eq {
  1540.           2 div exch 2 div exch sub    % centered
  1541.         } {
  1542.           sub            % right justified (hrect - hsize)
  1543.         } ifelse
  1544.       } ifelse
  1545.         % stack: scalex scaley annot V vsize vrect hoffset
  1546.       % Center the text vertically in the rect (Acrobat Reader seems to do this)
  1547.       3 1 roll 2 div exch 2 div sub abs
  1548.         % stack: scalex scaley annot V hoffset voffset
  1549.       moveto show
  1550.       Q
  1551.     } if
  1552.       } if
  1553.     } if
  1554.   } ifelse
  1555.   pop pop pop
  1556. } bdef
  1557.  
  1558. %  For annotation object we have to determine the size of the output rectangle
  1559. %  and the size of the BBox for the form XObject. From these we calculate
  1560. %  a scale factors for drawing it.
  1561. /calc_annot_scale {        % <annot> calc_annot_scale <x_scale> <y_scale>
  1562.   dup /Rect knownoget {
  1563.     pop dup annotrect 4 2 roll pop pop     % get width height size in user space
  1564.     3 -1 roll /AP knownoget {
  1565.       /N knownogetdict {
  1566.     dup /Matrix knownoget not { {1 0 0 1 0 0} } if
  1567.     exch /BBox knownoget {  % x y  {matrix} [box]
  1568.           exch .bbox_transform  % x y  x0 y0 x1 y1
  1569.           3 -1 roll sub         % x y  x0 x1 y1-y0
  1570.           3 1 roll exch sub     % x y  y1-y0 x1-x0 
  1571.           2 copy mul 0 eq {
  1572.             (   **** Warning: /BBox has zero width or height, which is not allowed.\n)
  1573.             pdfformaterror
  1574.             pop pop pop pop 1 1    % zero size -- revert to unity scaling
  1575.           } { 
  1576.         3 1 roll div        % x x1-x0 y/(y1-y0)
  1577.             3 1 roll div        % y/(y1-y0) x/(x1-x0)
  1578.             exch                % x/(x1-x0) y/(y1-y0)
  1579.           } ifelse
  1580.     } {
  1581.       pop pop pop 1 1    % default to unity scaling
  1582.     } ifelse        % if we have /BBox
  1583.       } {
  1584.     pop pop 1 1
  1585.       } ifelse            % if we have /N
  1586.     } {
  1587.       pop pop 1 1
  1588.     } ifelse            % if we have /AP
  1589.   } {
  1590.     (   **** Warning: /Annot dict is missing required /Rect entry.\n)
  1591.     pdfformaterror
  1592.     pop 1 1
  1593.   } ifelse
  1594. } bdef
  1595.  
  1596. /drawlink {            % <annot> drawlink -
  1597.   dup drawborder dup calc_annot_scale 3 -1 roll drawwidget
  1598. } bdef
  1599.  
  1600. % Draw an annotation.
  1601. /drawannottypes mark
  1602.   /Link { drawlink } bind
  1603. .dicttomark readonly def
  1604. /drawannot {        % <annot> drawannot -
  1605.   dup annotvisible {
  1606.     gsave
  1607.     dup dup /Subtype knownoget {
  1608.       //drawannottypes exch .knownget {
  1609.         exec
  1610.       } {
  1611.         dup calc_annot_scale 3 -1 roll drawwidget    % Use drawwidget for everything else
  1612.       } ifelse            % type known
  1613.     } {
  1614.       pop
  1615.       (   **** Warning: /Annot dict without required /Subtype entry is ignored.\n)
  1616.       pdfformaterror
  1617.     } ifelse
  1618.     grestore
  1619.   } if pop            % annotvisible
  1620. } bdef
  1621. currentdict /drawannottypes undef
  1622.  
  1623. % ============================ AcroForm fields ============================ %
  1624.  
  1625. % Get an attribure of the 0th annotation of a node
  1626. /annot_oget {  % <annot> /Name annot_oget <value>
  1627.   1 index /Kids knownoget {
  1628.     0 oget exch oget exch pop
  1629.   } {
  1630.     oget
  1631.   } ifelse
  1632. } bdef
  1633.  
  1634. % All procedures have the signature:
  1635. % <acroform> <field> <annot|field> foo <acroform> <field> <annot|field>
  1636. /draw_terminal_field_dict 4 dict begin
  1637.  
  1638. /Btn {
  1639.   1 index /Tf pget not { 0 } if
  1640.   dup 16#20000 and 0 ne {
  1641.     pop % Push button
  1642.     dup /AP known {
  1643.       1 1 2 index drawwidget
  1644.     } {
  1645.       (Push button without appearance stream is not yet implemented) =
  1646.     } ifelse
  1647.   } {
  1648.     16#10000 and 0 ne {
  1649.         % Radio button
  1650.         dup /AP known {
  1651.           1 index /Kids oget {
  1652.             1 1 3 -1 roll drawwidget
  1653.           } forall
  1654.         } {
  1655.           (Radio button without appearance stream is not yet implemented) =
  1656.         } ifelse
  1657.     } {
  1658.         % Checkbox
  1659.         dup /AP known {
  1660.           dup 1 1 3 -1 roll drawwidget
  1661.         } {
  1662.           (CkeckBox without appearance stream is not yet implemented) =
  1663.         } ifelse
  1664.     } ifelse
  1665.   } ifelse
  1666. } bdef
  1667.  
  1668. /Tx {
  1669.   dup /AP known {
  1670.     dup 1 1 3 -1 roll drawwidget
  1671.   } {
  1672.     2 index /NeedAppearances knownoget not { //false } if {
  1673.       dup /AP << /N 10 dict dup cvx begin >> put
  1674.       /Subtype /Form def
  1675.       /BBox [ 0 0 4 index /Rect oget { oforce } forall  3 -1 roll sub abs 3 1 roll sub abs exch ] def
  1676.       /Resources 3 index /DR pget not { 0 dict } if def
  1677.       /File 1000 string dup 3 1 roll def
  1678.       /Length 0 def
  1679.                             % <acroform> <field> <annot> (string)
  1680.       /NullEncode filter    % <acroform> <field> <annot> file 
  1681.  
  1682.       dup (BT ) writestring
  1683.       2 index /DA pget not { () } if
  1684.       [ exch
  1685.         { token {
  1686.             dup /Tf eq {
  1687.               2 index 0 eq {
  1688.                 /BBox load 3 get
  1689.                 0.75 mul   % empirical constant
  1690.                 4 -1 roll pop 3 1 roll
  1691.               } if
  1692.             } if
  1693.             exch
  1694.           } {
  1695.             exit
  1696.           } ifelse
  1697.         } loop
  1698.       ]
  1699.       { 1 index exch write== } forall
  1700.       dup 3 index /MaxLen pget not { 0 } if write=
  1701.       dup 3 index /V pget not { () } if write==
  1702.       dup 3 index /Ff pget not { 0 } if write=
  1703.       dup 3 index /Q pget not { 0 } if write=
  1704.       dup (Tform ET) write=
  1705.       end
  1706.       closefile             %  <acroform> <field> <annot>
  1707.       dup 1 1 3 -1 roll drawwidget
  1708.     } if
  1709.   } ifelse
  1710. } bdef
  1711.  
  1712. /Ch {
  1713.   (Ch is not yet implemened) ==
  1714. } bdef
  1715.  
  1716. /Sig {
  1717.   (Sig is not yet implemened ) ==
  1718. } bdef
  1719.  
  1720. currentdict end def
  1721.  
  1722. /draw_terminal_field {   % <field> draw_terminal_field -
  1723.  dup /Kids knownoget { 0 oget } { dup } ifelse
  1724.  dup /P knownoget {
  1725.     /Page load eq {
  1726.       //draw_terminal_field_dict 2 index /FT pget not { 0 } if .knownget {
  1727.         exec
  1728.       } if
  1729.    } if
  1730.  } if
  1731.  pop pop
  1732. } bdef
  1733.  
  1734. % We distinguish 4 types of nodes on the form field tree:
  1735. %  - non-terminal field - has a kid that refers to the parent (or anywhere else)
  1736. %  - terminal field with separate widget annotations - has a kid that doesn't have a parent
  1737. %  - terminal field with a merged widget annotation - has no kids
  1738. %  - widget annotation - has /Subtype and /Rect
  1739. %
  1740. % The recursive enumeration of the form fields doesn't descend into widget annotations.
  1741.  
  1742. /draw_form_field { % <field> draw_form_field -
  1743.   dup /Kids knownoget {                       % field []
  1744.     dup 0 oget /Parent knownoget {            % field [] kid
  1745.       pop % mon-terminal field                % field []
  1746.       exch pop                                % []
  1747.       { oforce draw_form_field } forall
  1748.     } {
  1749.       pop draw_terminal_field % separate annots % -
  1750.     } ifelse
  1751.   } {
  1752.     draw_terminal_field % merged annotation   % -
  1753.   } ifelse
  1754. } bdef
  1755.  
  1756. /draw_acro_form {        % <form> draw_acro_form -
  1757.   dup /Fields knownoget {
  1758.     { oforce draw_form_field } forall
  1759.   } if
  1760.   pop 
  1761. } bdef
  1762.  
  1763. currentdict /draw_terminal_field_dict undef
  1764.  
  1765. end            % pdfdict
  1766. end            % GS_PDF_ProcSet
  1767. .setglobal
  1768.